package cn.uyunsky.platform.data;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import cn.uyunsky.platform.util.PL;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;

/**
 * <p>Description: JSON转换工具类,使用FASTJSON;保证工程中其他位置不引用com.alibaba.fastjson</p>
 *
 * @version 1.0
 * @date 2012-1-20
 */
public class JsonTool {

    private static SerializeConfig mapping = new SerializeConfig();

    static {
        mapping.put(java.sql.Date.class, new SimpleDateFormatSerializer(PL.DATE_FORMAT));
        mapping.put(java.sql.Time.class, new SimpleDateFormatSerializer(PL.TIME_FORMAT));
        mapping.put(java.sql.Timestamp.class, new SimpleDateFormatSerializer(PL.TIMESTAMP_FORMAT));
        mapping.put(java.util.Date.class, new SimpleDateFormatSerializer(PL.TIMESTAMP_FORMAT));
    }

    static SerializerFeature[] features = {
            SerializerFeature.WriteMapNullValue, //空值是否输出null,避免undefined
            SerializerFeature.WriteNullListAsEmpty, //list字段如果为null，输出为[]，方便界面只判断length
            SerializerFeature.WriteNullBooleanAsFalse //Boolean字段如果为null，方便界面直接使用
    };

    public SerializeConfig getMapping() {
        return mapping;
    }

    public static String toJSON(Object o) {
        return JSON.toJSONString(o, mapping, features);
    }

    public static String toJSON(Object o, SerializeConfig mapping) {
        return JSON.toJSONString(o, mapping, features);
    }

    public static byte[] toJSONByte(Object o) {
        return JSON.toJSONBytes(o, mapping, features);
    }

    public byte[] toJSONByte(Object o, SerializeConfig mapping) {
        return JSON.toJSONBytes(o, mapping, features);
    }

    public static Map<?, ?> fromJSON(String json) {
        return JSON.parseObject(json);
    }

    public <T> T fromJSON(String json, Class<T> clazz) {
        return JSON.parseObject(json, clazz);
    }

    /**
     * json字符串的格式化
     *
     * @param json           需要格式的json串
     * @param fillStringUnit 每一层之前的占位符号比如空格 制表符
     * @return
     */
    public static String formatJson(String json, String fillStringUnit) {
        if (json == null || json.trim().length() == 0) {
            return null;
        }

        int fixedLenth = 0;
        ArrayList<String> tokenList = new ArrayList<String>();
        {
            String jsonTemp = json;
            //预读取
            while (jsonTemp.length() > 0) {
                String token = getToken(jsonTemp);
                jsonTemp = jsonTemp.substring(token.length());
                token = token.trim();
                tokenList.add(token);
            }
        }

        for (int i = 0; i < tokenList.size(); i++) {
            String token = tokenList.get(i);
            int length = token.getBytes().length;
            if (length > fixedLenth && i < tokenList.size() - 1 && tokenList.get(i + 1).equals(":")) {
                fixedLenth = length;
            }
        }

        StringBuilder buf = new StringBuilder();
        int count = 0;
        for (int i = 0; i < tokenList.size(); i++) {

            String token = tokenList.get(i);

            if (token.equals(",")) {
                buf.append(token);
                doFill(buf, count, fillStringUnit);
                continue;
            }
            if (token.equals(":")) {
                buf.append(" ").append(token).append(" ");
                continue;
            }
            if (token.equals("{")) {
                String nextToken = tokenList.get(i + 1);
                if (nextToken.equals("}")) {
                    i++;
                    buf.append("{ }");
                } else {
                    count++;
                    buf.append(token);
                    doFill(buf, count, fillStringUnit);
                }
                continue;
            }
            if (token.equals("}")) {
                count--;
                doFill(buf, count, fillStringUnit);
                buf.append(token);
                continue;
            }
            if (token.equals("[")) {
                String nextToken = tokenList.get(i + 1);
                if (nextToken.equals("]")) {
                    i++;
                    buf.append("[ ]");
                } else {
                    count++;
                    buf.append(token);
                    doFill(buf, count, fillStringUnit);
                }
                continue;
            }
            if (token.equals("]")) {
                count--;
                doFill(buf, count, fillStringUnit);
                buf.append(token);
                continue;
            }

            buf.append(token);
            //左对齐
            if (i < tokenList.size() - 1 && tokenList.get(i + 1).equals(":")) {
                int fillLength = fixedLenth - token.getBytes().length;
                if (fillLength > 0) {
                    for (int j = 0; j < fillLength; j++) {
                        buf.append(" ");
                    }
                }
            }
        }
        return buf.toString();
    }

    private static String getToken(String json) {
        StringBuilder buf = new StringBuilder();
        boolean isInYinHao = false;
        while (json.length() > 0) {
            String token = json.substring(0, 1);
            json = json.substring(1);

            if (!isInYinHao
                    && (token.equals(":") || token.equals("{") || token.equals("}") || token.equals("[")
                    || token.equals("]") || token.equals(","))) {
                if (buf.toString().trim().length() == 0) {
                    buf.append(token);
                }

                break;
            }

            if (token.equals("\\")) {
                buf.append(token);
                buf.append(json.substring(0, 1));
                json = json.substring(1);
                continue;
            }
            if (token.equals("\"")) {
                buf.append(token);
                if (isInYinHao) {
                    break;
                } else {
                    isInYinHao = true;
                    continue;
                }
            }
            buf.append(token);
        }
        return buf.toString();
    }

    private static void doFill(StringBuilder buf, int count, String fillStringUnit) {
        buf.append("\n");
        for (int i = 0; i < count; i++) {
            buf.append(fillStringUnit);
        }
    }


    public static void main(String[] args) {
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        Map r = new HashMap();
        r.put("registerDate", timestamp);
        System.out.println(JsonTool.toJSON(r));
    }
}
